#pragma once
#include"detail.hpp"
#include"abstract.hpp"
#include"field.hpp"
#include<unordered_map>
#include<mutex>



namespace RPC_project
{
    class Callback
    {
    public: 
        using ptr=std::shared_ptr<Callback>;
        virtual void onMessage(const BaseConnection::ptr& conn, BaseMessage::ptr& msg) = 0;

    };

    //Callback专门存储handler
    template<typename T>
    class CallbackT : public Callback
    {
    public:
        using ptr=std::shared_ptr<CallbackT<T>>;
        using MessageCallback =std::function<void (const BaseConnection::ptr& , std::shared_ptr<T>& )>;
        CallbackT (const MessageCallback& handler) :_handler(handler){}

        void onMessage(const BaseConnection::ptr& conn, BaseMessage::ptr& msg) override
        {
            auto type_msg = std::dynamic_pointer_cast<T>(msg);
            _handler(conn , type_msg);
        }

    private:
        MessageCallback _handler;
    };


    class Dispather
    {
    public:
        using ptr =std::shared_ptr<Dispather>;
        //设置成模版函数 ,让设置的回调函数类型可以不同 ,减少用户使用成本
        template<typename T >
        void RegisterHandler(MType mtype, const typename CallbackT<T>::MessageCallback& handler)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto cb =std::make_shared<CallbackT<T>>(handler);
            _handlers.insert(std::make_pair(mtype, cb));

        }

        //根据消息类型格式 ,找到对应的业务处理函数 ,并直接进行调用
        void onMessage(const BaseConnection::ptr& conn, BaseMessage::ptr& msg)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it =_handlers.find(msg->MyType());
            if(it !=_handlers.end())
            {
               return  it->second->onMessage(conn ,msg);//注意需要return 
            }
            ELOG("收到错误类型消息:" "%d" ,(int)msg->MyType());
            conn->Shutdown();
        }


    private:   
        std::mutex _mutex;
        //利用多态解决统一容器中不能存储不同类型的问题
        std::unordered_map<MType , Callback::ptr> _handlers;
    };
    
}